package com.jxy.homepage.security.jwt;

import io.jsonwebtoken.*;
import io.lettuce.core.codec.CompressionCodec;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.*;
import java.util.stream.Collectors;

/**
 * JwtTokenUtils
 *
 * @author Jxy
 * @date 2022/1/9
 * @Description Jwt
 */
@Component
public class JwtTokenUtils implements InitializingBean {

    private static final String AUTHORITIES_KEY = "auth";
    private final JwtSecurityProperties jwtSecurityProperties;

    public JwtTokenUtils(JwtSecurityProperties jwtSecurityProperties) {
        this.jwtSecurityProperties = jwtSecurityProperties;
    }

    @Override
    public void afterPropertiesSet() {
    }


    public String createToken(Map<String, Object> claims) {
        return Jwts.builder()
                .claim(AUTHORITIES_KEY, claims)
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setExpiration(new Date((new Date()).getTime() + jwtSecurityProperties.getTokenValidityInSeconds()))
                // 压缩签名
                .compressWith(CompressionCodecs.DEFLATE)
                .signWith(SignatureAlgorithm.HS512, jwtSecurityProperties.getSecret())
                .compact();
    }

    /**
     * 0 token 过期 1 成功 -1 不成功
     *
     * @param token
     * @return int
     */
    public int verifyToken(String token) {
        try {
            Jwts.parser().setSigningKey(jwtSecurityProperties.getSecret()).parseClaimsJws(token);
            return 1;
        } catch (ExpiredJwtException e) {
            return 0;
        } catch (Exception e) {
            return -1;
        }
    }

    public Authentication getAuthentication(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtSecurityProperties.getSecret())
                .parseClaimsJws(token)
                .getBody();

        Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
        Map o = (Map)claims.get(AUTHORITIES_KEY);

        User principal = new User((String) o.get("user"),(String) o.get("password"),authorities);
        return new UsernamePasswordAuthenticationToken(principal, token, authorities);
    }
}
